// 封装的ajax请求函数
function myAjax( resObj = {} ) {
    // 设定默认值对象 
    const valObj = {
        // 请求方式
        type: 'get',
        // 携带参数
        data: '',
        // 请求地址
        url: '',
        // 请求成功触发执行的程序
        success: () => { },
        // 请求失败触发执行的程序
        error: () => { },
    };

    // 如果 实参对象中 data属性 存储的是对象形式 { name:'张三' , age:18 }
    // 需要 转化为 键值对字符串形式  'name=张三&age=18'
    if (typeof (resObj.data) === 'object') {
        // 定义空字符串 存储 结果 
        let str = '';

        // 循环遍历 携带参数对象 也就是 resObj.data 中 存储的对象 
        for (let key in resObj.data) {
            // key 是 对象的键名 也就是 name  age ...
            // resObj.data[key] 是 对象的键值 也就是 张三 18 ...
            str += `&${key}=${resObj.data[key]}`;
        }

        // 将拼接好的字符串 赋值给 resObj.data 存储 
        // 也就是将 原始存储的对象 覆盖成 拼接好的字符串 
        resObj.data = str.substr(1);
    }


    // 循环遍历默认值对象 
    for (let key in valObj) {
        // 使用 默认值对象中的键名 去 实参对象中调用数据
        if (resObj[key] !== undefined) {
            // 如果调用结果不是undefined 证明 实参对象中 有默认值数据 
            // 将实参对象中的数据 覆盖 默认值对象中的数据
            valObj[key] = resObj[key];
        }
    }


    // 创建ajax实例化对象
    const xhr = new XMLHttpRequest();
    console.log(xhr);

    // 根据请求类型执行不同的 设定步骤
    // 判断 get/post 请求方式 要统一大小写
    if (valObj.type.toLowerCase() === 'get') {
        // 设定open()

        // 如果 携带参数也就是valObj.data 是 空字符串 证明没有携带参数 
        // 那么 open()方法 参数2 只设定 请求的url地址

        // 如果 携带参数也就是valObj.data 不是 空字符串 证明需要携带参数 
        // 那么 open()方法 参数2 请求的url地址 拼接问号 拼接 携带参数

        // xhr.open( 'get' , valObj.data === '' ? valObj.url : valObj.url + '?' + valObj.data );

        xhr.open('get', valObj.data === '' ? valObj.url : `${valObj.url}?${valObj.data}`);

        // 设定send()发送请求携带参数
        xhr.send();

    } else if (valObj.type.toLowerCase() === 'post') {
        // 设定open()
        xhr.open('post', valObj.url);

        // 固定的请求头设定
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

        // 设定send() 如果有参数携带参数
        xhr.send(valObj.data);
    }

    // 接收请求结果
    xhr.addEventListener('load', () => {

        // 请求结束触发的回调函数
        // xhr.response 或者 xhr.responseText 中 存储的是 响应体结果
        // 回调函数的执行 需要 根据 响应体结果触发执行

        // 判断 ajax状态码是4 http状态码是200-299 请求结束并且请求成功并且解析响应体数据
        if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {
            // 请求结束 并且 请求成功 并且 解析响应体数据
            valObj.success(xhr.response);

        } else {
            // 请求结束 但是 请求失败
            valObj.error();
        }
    })

}


// 封装使用 promise 调用 ajax程序
function myPromiseAjax( resObj = {} ) {

    // 创建promise实例化对象
    const p = new Promise(function ( fulfilled , rejected ) {
        // 设定默认值对象 
        const valObj = {
            // 请求方式
            type: 'get',
            // 携带参数
            data: '',
            // 请求地址
            url: '',
        };

        // 如果携带参数是对象类型 拼接成字符串
        if (typeof (resObj.data) === 'object') {
            // 定义空字符串 存储 结果 
            let str = '';
            for (let key in resObj.data) {
                str += `&${key}=${resObj.data[key]}`;
            }
            resObj.data = str.substr(1);
        }


        // 将实参数据覆盖默认值数据 
        for (let key in valObj) {
            if (resObj[key] !== undefined) {
                valObj[key] = resObj[key];
            }
        }

        // 创建ajax实例化对象
        const xhr = new XMLHttpRequest();

        // 根据请求类型执行不同的 设定步骤
        // 判断 get/post 请求方式 要统一大小写
        if (valObj.type.toLowerCase() === 'get') {
            // 设定open()
            xhr.open('get', valObj.data === '' ? valObj.url : `${valObj.url}?${valObj.data}`);

            // 设定send()发送请求携带参数
            xhr.send();

        } else if (valObj.type.toLowerCase() === 'post') {
            // 设定open()
            xhr.open('post', valObj.url);

            // 固定的请求头设定
            xhr.setRequestHeader('Content-Type', 'application/json');

            // 设定send() 如果有参数携带参数
            xhr.send(valObj.data);
        }

        // 接收请求结果
        xhr.addEventListener('load', () => {
            // 判断 ajax状态码是4 http状态码是200-299 请求结束并且请求成功并且解析响应体数据

            // 原来执行的是 参数对象中存储的 success 和 error 对应的函数程序 
            // 现在执行的是 promise通过 .then 和 .catch 赋值的函数程序

            if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {
                // valObj.success( xhr.response );

                // 请求结束 并且 请求成功 并且 解析响应体数据
                fulfilled(xhr.response);

            } else {
                // valObj.error();


                // 请求结束 但是 请求失败
                rejected();
            }
        })

    });


    // 返回promise对象
    return p;
}